home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 2855 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.5 KB  |  108 lines

  1. Path: news.iag.net!news
  2. From: jatmon@iag.net (John R Buchan)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: sscanf problems
  5. Date: 24 Jan 1996 15:09:29 GMT
  6. Organization: Internet Access Group, Orlando, Florida
  7. Message-ID: <4e5i39$2e6@news.iag.net>
  8. References: <4e4c2v$j2g@mathserv.mps.ohio-state.edu>
  9. NNTP-Posting-Host: pm2-orl16.iag.net
  10. X-Newsreader: WinVN 0.99.7
  11.  
  12. In article <4e4c2v$j2g@mathserv.mps.ohio-state.edu>, 
  13. cmongold@magnus.acs.ohio-state.edu says...
  14. >
  15. >Hello,
  16. >        I'm sorry if this is an inappropriate topic, but I've tried
  17. >everything else.  I can't seem to get sscanf to to separate a string
  18. >into various variable types.  Here is an example:
  19. >
  20. >#include <stdio.h>
  21. >
  22. >void main()
  23.  
  24. main must return int in any ansi c code. A return of void is undefined.  
  25.  
  26. >{
  27. >char input[20], crap[17], segment[6], seg_len[3], begin[3], load[3];
  28. >int type;
  29. >FILE *fp;
  30. >
  31. >printf("File: ");
  32. >gets(input);
  33.  
  34. Use fgets(input, sizeof(input), stdin);  This allows you to protect your
  35. array bounds. gets offers no such protection.
  36.  
  37. >
  38. >fp = fopen(input, "r");
  39.  
  40. I assume you've left out the tests for the sake of brevity?
  41.  
  42. if( fp != NULL)
  43.    {
  44.    /* handle the failed open */
  45.    }
  46.  
  47. >
  48. >while(!feof(fp))
  49.  
  50. The faq list explains why this test is not a good idea.  Try:
  51.  
  52.    fgets(crap, sizeof(crap), fp);
  53.  
  54. >{
  55. >fgets(crap, 17, fp);
  56.  
  57. Avoid hard coding your sizes, when possible.  Either use #defines or, if
  58. the buffer was defined as a char array, use sizeof.
  59.  
  60. >sscanf(crap, "%d%3s%6s%3s%3s", type, begin, segment, seg_len, load);
  61.  
  62. sscanf a pointer to a valid storage location for an object of the type 
  63. indicated by the conversion specifier.  You specified an int "%d", then
  64. passed the value of the uninitialized int 'type', instead of its address.
  65. You should have used &type. In a variable argument list, the compiler has 
  66. no way of knowing the correct type of any passes argument. So, it can not
  67. warn you, when you pass the wrong type.  You must make certain to pass the 
  68. correct type.
  69.  
  70. Since an array name decays to a pointer to its first element, you are 
  71. correct with the types of the other arguments.  However, you are not 
  72. allowing room for the '\0' that sscanf will append.  After sscanf reads 3
  73. chars and stores them in 'begin', it will add a '\0' to make 'begin' a legal
  74. string ("%s" indicates that you want a string).  This means that it will 
  75. actually store 4 chars in 'begin'.  Since begin was defined for only 3, you
  76. just overwrote the first char of whatever happened to follow it in memory.
  77.  
  78. If you want to literally read 3 chars and are not going to use them as a 
  79. string, use "%3c".  However, this specifier will not react to white spaces
  80. the same as "%s".  So you need to look closely at it.
  81.  
  82. You should make a point to test the return value of sscanf against the
  83. number of fields you expected to read.  It is the only way to ensure that
  84. you actually read the correct number.
  85.  
  86. >printf("%d %3s %6s %3s %3s", type, begin, segment, seg_len, load);
  87. >
  88.  
  89. You will need a return statement here to match the correct definition of main.
  90.  
  91. return 0;
  92.  
  93. >}
  94. >}
  95. >No matter what I do, it always 'bus errors' when I sscanf.  I've tried
  96. >it several different ways, including making crap larger, but to
  97. >no avail.  If anyone can help me, I would greatly appreciate it.
  98.  
  99. The bus error was most likely a result of your sscanf, not the fgets.
  100.  
  101. Most of this is explained in the c.l.c faq (Frequently Asked Question) list.  
  102. You can d/l it by anonymous ftp from rtfm.mit.edu /pubusenet/comp.lang.c.
  103.  
  104. -- 
  105. John R Buchan           -:|:-     Looking for that elusive FAQ?  ftp to:
  106. jatmon@mail.iag.net     -:|:-     rtfm.mit.edu /pub/usenet-by-group/....
  107.  
  108.